﻿using Microsoft.Extensions.DependencyInjection;
using OpenCvSharp.Internal.Vectors;
using System.Diagnostics;
using System.Threading;
using VIA.Integration;
using VIA.Integration.Alarms;
using VIA.Integration.Domain;
using VIA.Integration.LeadShine;
using VIA.Project.Domain.Services;
using VIA.SiMoJi.Domain.Electronics;
using VIA.SiMoJi.Domain.Option;

namespace VIA.SiMoJi.Domain.Inspection
{
    public class BuJinPiDai : Automatic, IHasOption<BuJinPiDaiStationOption>, ISuportInitialization, ISuportClearAlarm
    {
        internal const string _运行高速 = "运行高速";
        internal const string _运行低速 = "运行低速";
        public Electronic Electronic => Electronic.Default;
        public DmcAxis Axis_PiDai1 { get; }
        public DmcAxis Axis_PiDai2 { get; }
        public BuJinPiDaiStationOption Option { get; set; }
        public BuJinPiDai(DmcAxis pidai1, DmcAxis pidai2)
        {
            Axis_PiDai1 = pidai1;
            Axis_PiDai2 = pidai2;
        }
        public void ClearAlarm()
        {
            Axis_PiDai1.ClearAlarm();
            Axis_PiDai2.ClearAlarm();
        }
        public void AxisRun(CancellationToken cancellationToken, bool isYouliao = false)
        {
            #region TODO:保证每一次运行参数有效
            var axis_PiDaiOption1 = Recipe.Get<AxisOption>(Axis_PiDai1.Id);
            var axis_PiDaiOption2 = Recipe.Get<AxisOption>(Axis_PiDai2.Id);
            Axis_PiDai1.Option = axis_PiDaiOption1;
            Axis_PiDai2.Option = axis_PiDaiOption2;
            #endregion
            if (Axis_PiDai1.IsDone)
            {
                var cSpeed = Axis_PiDai1.GetVelocityCurve(_运行高速);
                if (Electronic.DI39_入料到位减速光电.Value && !Electronic.DI21_入料到位光电.Value)
                    cSpeed = Axis_PiDai1.GetVelocityCurve(_运行低速);
                if (cSpeed == null)
                    cSpeed = Axis_PiDai1.GetCurrentVelocityCurve();
                AxisPositiveMove(cSpeed, cancellationToken);
                #region TODO  注释原因会连续来料风险
                if (!isYouliao)
                {
                    Electronic.DO93_上料交互输出信号1模组继电器.Value = true;
                    Electronic.DO94_上料交互输出信号2模组继电器.Value = true;
                }
                Electronic.DO95_下料交互输出信号1模组继电器.Value = false;
                Electronic.DO96_下料交互输出信号2模组继电器.Value = false;
                #endregion
            }
        }
        public void AxisStop()
        {
            #region TODO  注释原因会连续来料风险
            Electronic.DO93_上料交互输出信号1模组继电器.Value = false;
            Electronic.DO94_上料交互输出信号2模组继电器.Value = false;
            Electronic.DO95_下料交互输出信号1模组继电器.Value = false;
            Electronic.DO96_下料交互输出信号2模组继电器.Value = false;
            #endregion
            AxisStopMove();
        }
        /// <summary>
        /// 正向高速转动
        /// </summary>
        /// <param name="cancelToken"></param>
        /// <returns></returns>
        public async Task PostiveRunning(CancellationToken cancelToken)
        {
            var highSpeed1 = Axis_PiDai1.GetVelocityCurve(_运行高速);
            var highSpeed2 = Axis_PiDai2.GetVelocityCurve(_运行高速);
            if (Axis_PiDai1.IsDone && Axis_PiDai2.IsDone)
            {
                await Task.WhenAll(Axis_PiDai1.NegativeAsync(highSpeed1, cancelToken), Axis_PiDai2.PostiveAsync(highSpeed2, cancelToken));
            }
        }
        /// <summary>
        /// 正向低速转动
        /// </summary>
        /// <param name="cancelToken"></param>
        /// <returns></returns>
        public async Task LowPostiveRunning(CancellationToken cancelToken)
        {
            var lowSpeed1 = Axis_PiDai1.GetVelocityCurve(_运行低速);
            var lowSpeed2 = Axis_PiDai2.GetVelocityCurve(_运行低速);
            if (Axis_PiDai1.IsDone && Axis_PiDai2.IsDone)
            {
                await Task.WhenAll(Axis_PiDai1.NegativeAsync(lowSpeed1, cancelToken), Axis_PiDai2.PostiveAsync(lowSpeed2, cancelToken));
            }
        }

        /// <summary>
        /// 反向高速转动
        /// </summary>
        /// <param name="cancelToken"></param>
        /// <returns></returns>
        public async Task NegativeRunning(CancellationToken cancelToken)
        {
            var highSpeed1 = Axis_PiDai1.GetVelocityCurve(_运行高速);
            var highSpeed2 = Axis_PiDai2.GetVelocityCurve(_运行高速);
            if (Axis_PiDai1.IsDone && Axis_PiDai2.IsDone)
            {
                await Task.WhenAll(Axis_PiDai1.PostiveAsync(highSpeed1, cancelToken), Axis_PiDai2.NegativeAsync(highSpeed2, cancelToken));
            }
        }
        /// <summary>
        /// 反向底速转动
        /// </summary>
        /// <param name="cancelToken"></param>
        /// <returns></returns>
        public async Task LowNegativeRunning(CancellationToken cancelToken)
        {
            var lowSpeed1 = Axis_PiDai1.GetVelocityCurve(_运行低速);
            var lowSpeed2 = Axis_PiDai2.GetVelocityCurve(_运行低速);
            if (Axis_PiDai1.IsDone && Axis_PiDai2.IsDone)
            {
                await Task.WhenAll(Axis_PiDai1.PostiveAsync(lowSpeed1, cancelToken), Axis_PiDai2.NegativeAsync(lowSpeed2, cancelToken));
            }
        }
        /// <summary>
        /// 在线变速
        /// </summary>
        /// <param name="isHigh">True:高速 False：低速</param>
        public void ChangeSpeed(bool isHigh = false)
        {
            VelocityCurve velocity1 = Axis_PiDai1.GetVelocityCurve(_运行低速);
            VelocityCurve velocity2 = Axis_PiDai2.GetVelocityCurve(_运行低速);
            if (isHigh)
            {
                velocity1 = Axis_PiDai1.GetVelocityCurve(_运行高速);
                velocity2 = Axis_PiDai2.GetVelocityCurve(_运行高速);
            }
            Axis_PiDai1.ChangeSpeed(-velocity1.Maxvel, velocity1.Tacc);
            Axis_PiDai2.ChangeSpeed(velocity2.Maxvel, velocity2.Tacc);
        }
        /// <summary>
        /// 停止转动
        /// </summary>
        /// <returns></returns>
        public async Task Stop()
        {
            await Task.WhenAll(Axis_PiDai1.PauseAsync(), Axis_PiDai2.PauseAsync());
        }
        /// <summary>
        /// 上游交互请求打开
        /// </summary>
        public void LoadYouOpen()
        {
            Electronic.DO93_上料交互输出信号1模组继电器.Value = true;
            Electronic.DO94_上料交互输出信号2模组继电器.Value = true;
        }

        /// <summary>
        /// 上游交互请求关闭
        /// </summary>
        public void LoadYouClose()
        {
            Electronic.DO93_上料交互输出信号1模组继电器.Value = false;
            Electronic.DO94_上料交互输出信号2模组继电器.Value = false;
        }
        /// <summary>
        /// 下游交互请求打开(未启用)
        /// </summary>
        public void UnloadYouOpen()
        {
            Electronic.DO95_下料交互输出信号1模组继电器.Value = true;
            Electronic.DO96_下料交互输出信号2模组继电器.Value = true;
        }
        /// <summary>
        /// 下游交互请求关闭(未启用)
        /// </summary>
        public void UnloadYouClose()
        {
            Electronic.DO95_下料交互输出信号1模组继电器.Value = false;
            Electronic.DO96_下料交互输出信号2模组继电器.Value = false;
        }

        public void AxisPositiveMove(VelocityCurve velocityCurve, CancellationToken cancellationToken)
        {
            Parallel.Invoke(async () =>
             {
                 try
                 {
                     if (Axis_PiDai1.IsDone)
                         await Axis_PiDai1.NegativeAsync(velocityCurve, cancellationToken);
                 }
                 catch (Exception ex)
                 {
                     Debug.WriteLine(ex);
                 }
             },
            async () =>
            {
                try
                {
                    if (Axis_PiDai2.IsDone)
                        await Axis_PiDai2.PostiveAsync(velocityCurve, cancellationToken);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex);
                }
            });
        }

        public void AxisNagetiveMove(double speed, CancellationToken cancellationToken)
        {
            Parallel.Invoke(
            async () =>
            {
                try
                {
                    if (Axis_PiDai1.IsDone)
                        await Axis_PiDai1.PostiveAsync(new VelocityCurve() { Maxvel = speed, Tacc = 0.1, Tdec = 0.1 }, cancellationToken);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex);
                }
            },
           async () =>
           {
               try
               {
                   if (Axis_PiDai2.IsDone)
                       await Axis_PiDai2.NegativeAsync(new VelocityCurve() { Maxvel = speed, Tacc = 0.1, Tdec = 0.1 }, cancellationToken);
               }
               catch (Exception ex)
               {
                   Debug.WriteLine(ex);
               }
           });
        }

        public void AxisStopMove()
        {
            Parallel.Invoke(
             async () =>
             {
                 try
                 {
                     await Axis_PiDai1.PauseAsync();
                 }
                 catch (Exception ex)
                 {
                     Debug.WriteLine(ex);
                 }
             },
            async () =>
            {
                try
                {
                    await Axis_PiDai2.PauseAsync();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex);
                }
            }
            );
        }

        public Task InitializeAsync()
        {
            return Task.CompletedTask;
        }
    }

    #region 旧程序
    //public class BuJinPiDai : Automatic, IHasOption<BuJinPiDaiStationOption>, ISuportInitialization, ISuportClearAlarm
    //{
    //    internal const string _运行高速 = "运行高速";
    //    internal const string _运行低速 = "运行低速";
    //    private InspectorOption _inspectorOption;
    //    public Electronic Electronic => Electronic.Default;
    //    public BujinPiDaiRunningStatus Status;
    //    public DmcAxis Axis_PiDai1 { get; }
    //    public DmcAxis Axis_PiDai2 { get; }
    //    public BuJinPiDaiStationOption Option { get; set; }
    //    public BuJinPiDai(DmcAxis pidai1, DmcAxis pidai2)
    //    {
    //        Axis_PiDai1 = pidai1;
    //        Axis_PiDai2 = pidai2;
    //    }
    //    public void ClearAlarm()
    //    {
    //        Axis_PiDai1.ClearAlarm();
    //        Axis_PiDai2.ClearAlarm();
    //    }

    //    public async Task<bool> InitializeStation(CancellationToken token)
    //    {
    //        AxisStop();
    //        return false;
    //    }

    //    public bool CheckIsRunningAllowed()
    //    {
    //        bool isAllowed = SignalPanel.Signal.AllowGongLiaoSensor && !Electronic.DI21_入料到位光电.Value && (Electronic.DI95_下料交互输入信号1模组继电器.Value || !Electronic.DI22_出料口光电.Value);
    //        return isAllowed;
    //    }

    //    public void AxisRun(CancellationToken cancellationToken, bool isYouliao = false)
    //    {
    //        #region TODO:保证每一次运行参数有效
    //        var axis_PiDaiOption1 = Recipe.Get<AxisOption>(Axis_PiDai1.Id);
    //        var axis_PiDaiOption2 = Recipe.Get<AxisOption>(Axis_PiDai2.Id);
    //        Axis_PiDai1.Option = axis_PiDaiOption1;
    //        Axis_PiDai2.Option = axis_PiDaiOption2;
    //        #endregion
    //        if (Axis_PiDai1.IsDone)
    //        {
    //            var cSpeed = Axis_PiDai1.GetVelocityCurve(_运行高速);
    //            if (Electronic.DI39_入料到位减速光电.Value && !Electronic.DI21_入料到位光电.Value)
    //                cSpeed = Axis_PiDai1.GetVelocityCurve(_运行低速);
    //            if (cSpeed == null)
    //                cSpeed = Axis_PiDai1.GetCurrentVelocityCurve();
    //            AxisPositiveMove(cSpeed, cancellationToken);
    //            #region TODO  注释原因会连续来料风险
    //            if (!isYouliao)
    //            {
    //                Electronic.DO93_上料交互输出信号1模组继电器.Value = true;
    //                Electronic.DO94_上料交互输出信号2模组继电器.Value = true;
    //            }
    //            Electronic.DO95_下料交互输出信号1模组继电器.Value = false;
    //            Electronic.DO96_下料交互输出信号2模组继电器.Value = false;
    //            #endregion
    //        }
    //    }

    //    public void AxisStop()
    //    {
    //        #region TODO  注释原因会连续来料风险
    //        Electronic.DO93_上料交互输出信号1模组继电器.Value = false;
    //        Electronic.DO94_上料交互输出信号2模组继电器.Value = false;
    //        Electronic.DO95_下料交互输出信号1模组继电器.Value = false;
    //        Electronic.DO96_下料交互输出信号2模组继电器.Value = false;
    //        #endregion
    //        AxisStopMove();
    //    }

    //    /// <summary>
    //    /// 上游交互请求打开
    //    /// </summary>
    //    public void LoadYouOpen()
    //    {
    //        Electronic.DO93_上料交互输出信号1模组继电器.Value = true;
    //        Electronic.DO94_上料交互输出信号2模组继电器.Value = true;
    //    }

    //    /// <summary>
    //    /// 上游交互请求关闭
    //    /// </summary>
    //    public void LoadYouClose()
    //    {
    //        Electronic.DO93_上料交互输出信号1模组继电器.Value = false;
    //        Electronic.DO94_上料交互输出信号2模组继电器.Value = false;
    //    }
    //    /// <summary>
    //    /// 下游交互请求打开(未启用)
    //    /// </summary>
    //    public void UnloadYouOpen()
    //    {
    //        Electronic.DO95_下料交互输出信号1模组继电器.Value = true;
    //        Electronic.DO96_下料交互输出信号2模组继电器.Value = true;
    //    }
    //    /// <summary>
    //    /// 下游交互请求关闭(未启用)
    //    /// </summary>
    //    public void UnloadYouClose()
    //    {
    //        Electronic.DO95_下料交互输出信号1模组继电器.Value = false;
    //        Electronic.DO96_下料交互输出信号2模组继电器.Value = false;
    //    }
    //    ///// <summary>
    //    ///// 检测皮带是否在运动
    //    ///// </summary>
    //    ///// <returns></returns>
    //    //public bool CheckIsRunning(out double speed)
    //    //{
    //    //    var sp1 = Axis_PiDai1.GetSpeed();
    //    //    var sp2 = Axis_PiDai2.GetSpeed();
    //    //    speed = Math.Min(sp1, sp2);
    //    //    if (sp1 > double.Epsilon || sp1 > double.Epsilon)
    //    //        return true;
    //    //    return false;
    //    //}

    //    public void AxisPositiveMove(VelocityCurve velocityCurve, CancellationToken cancellationToken)
    //    {
    //        Parallel.Invoke(async () =>
    //         {
    //             try
    //             {
    //                 if (Axis_PiDai1.IsDone)
    //                     await Axis_PiDai1.NegativeAsync(velocityCurve, cancellationToken);
    //             }
    //             catch (Exception ex)
    //             {


    //             }
    //         },
    //        async () =>
    //        {
    //            try
    //            {
    //                if (Axis_PiDai2.IsDone)
    //                    await Axis_PiDai2.PostiveAsync(velocityCurve, cancellationToken);
    //            }
    //            catch (Exception ex)
    //            {


    //            }

    //        });
    //    }

    //    public void AxisNagetiveMove(double speed, CancellationToken cancellationToken)
    //    {
    //        Parallel.Invoke(
    //        async () =>
    //        {
    //            try
    //            {
    //                if (Axis_PiDai1.IsDone)
    //                    await Axis_PiDai1.PostiveAsync(new VelocityCurve() { Maxvel = speed, Tacc = 0.1, Tdec = 0.1 }, cancellationToken);
    //            }
    //            catch (Exception ex) { }
    //        },
    //       async () =>
    //       {
    //           try
    //           {
    //               if (Axis_PiDai2.IsDone)
    //                   await Axis_PiDai2.NegativeAsync(new VelocityCurve() { Maxvel = speed, Tacc = 0.1, Tdec = 0.1 }, cancellationToken);
    //           }
    //           catch (Exception ex) { }
    //       });
    //    }

    //    public void AxisStopMove()
    //    {
    //        Parallel.Invoke(
    //         async () =>
    //         {
    //             try
    //             {
    //                 await Axis_PiDai1.PauseAsync();
    //             }
    //             catch (Exception)
    //             {
    //             }
    //         },
    //        async () =>
    //        {
    //            try
    //            {
    //                await Axis_PiDai2.PauseAsync();
    //            }
    //            catch (Exception)
    //            {
    //            }
    //        }
    //        );
    //    }

    //    public async Task InitializeAsync()
    //    {
    //        //Status = RunningStatus.GetRecord<BujinPiDaiRunningStatus>("BuJinPiDai.json");
    //        var repository = Service.GetRequiredService<IOptionRepository>();
    //        _inspectorOption = repository.Get<InspectorOption>();
    //    }
    //}
    #endregion
}
